package org.ovirt.engine.ui.uicommonweb.models.vms;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VMStatus;
import org.ovirt.engine.core.common.queries.HasAdElementReconnectPermissionParameters;
import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.ui.frontend.Frontend;
import org.ovirt.engine.ui.frontend.utils.BaseContextPathData;
import org.ovirt.engine.ui.uicommonweb.BaseCommandTarget;
import org.ovirt.engine.ui.uicommonweb.ErrorPopupManager;
import org.ovirt.engine.ui.uicommonweb.TypeResolver;
import org.ovirt.engine.ui.uicommonweb.UICommand;
import org.ovirt.engine.ui.uicommonweb.help.HelpTag;
import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel;
import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
import org.ovirt.engine.ui.uicommonweb.models.Model;
import org.ovirt.engine.ui.uicompat.ConstantsManager;
import org.ovirt.engine.ui.uicompat.Event;
import org.ovirt.engine.ui.uicompat.EventDefinition;
import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs;
import com.google.gwt.dom.client.FormElement;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;
public abstract class ConsoleModel extends EntityModel<VM> {
public static final String GET_ATTACHMENT_SERVLET_URL = BaseContextPathData.getPath()
+ "services/attachment/"; //$NON-NLS-1$
private static String EJECT_LABEL;
public static String getEjectLabel() {
if (EJECT_LABEL == null) {
EJECT_LABEL = "[" + ConstantsManager.getInstance().getConstants().eject() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
return EJECT_LABEL;
}
public static final EventDefinition errorEventDefinition;
private Event<ErrorCodeEventArgs> privateErrorEvent;
public Event<ErrorCodeEventArgs> getErrorEvent() {
return privateErrorEvent;
}
private void setErrorEvent(Event<ErrorCodeEventArgs> value) {
privateErrorEvent = value;
}
private UICommand privateConnectCommand;
public UICommand getConnectCommand() {
return privateConnectCommand;
}
private void setConnectCommand(UICommand value) {
privateConnectCommand = value;
}
private boolean forceVmStatusUp;
public boolean getForceVmStatusUp() {
return forceVmStatusUp;
}
public void setForceVmStatusUp(boolean value) {
if (forceVmStatusUp != value) {
forceVmStatusUp = value;
onPropertyChanged(new PropertyChangedEventArgs("ForceVmStatusUp")); //$NON-NLS-1$
}
}
/**
* This attribute is a workaround for displaying popup dialogs
* in console models.
*/
private final Model parentModel;
protected Model getParentModel() {
return parentModel;
}
static {
errorEventDefinition = new EventDefinition("Error", ConsoleModel.class); //$NON-NLS-1$
}
protected ConsoleModel(VM myVm, Model parentModel) {
this.parentModel = parentModel;
setEntity(myVm);
setErrorEvent(new Event<ErrorCodeEventArgs>(errorEventDefinition));
setConnectCommand(new UICommand("Connect", this)); //$NON-NLS-1$
}
protected abstract void connect();
public abstract boolean canBeSelected();
public boolean canConnect() {
if (!canBeSelected()) { // cannot be even selected
return false;
}
return getForceVmStatusUp()
? getEntity().getStatus() == VMStatus.Up
: getEntity().isQualifiedForConsoleConnect();
}
@Override
public void executeCommand(UICommand command) {
super.executeCommand(command);
if (command == getConnectCommand()) {
connect();
}
}
/**
* Executes given command. The confirmation dialog is displayed when it's
* not safe to take over the console, which is when
* - allow console reconnect is disabled AND
* - there is an active console user who is different from current portal user AND
* - current portal user has not reconnect permissions (this is to prevent extra information dialog. backend
* validation will not allow connecting this user and frontend will display warning message anyway)
*/
protected void executeCommandWithConsoleSafenessWarning(final UICommand command) {
VM vm = getEntity();
if (vm.getAllowConsoleReconnect() || vm.getConsoleUserId() == null ||
Frontend.getInstance().getLoggedInUser().getId().equals(vm.getConsoleUserId())) {
command.execute();
return;
}
//now we ask if the currently connected user has permission to reconnect (async)
final HasAdElementReconnectPermissionParameters consoleUserReconnectPermParams =
new HasAdElementReconnectPermissionParameters(vm.getConsoleUserId(),
vm.getId());
final HasAdElementReconnectPermissionParameters portalUserReconnectPermParams =
new HasAdElementReconnectPermissionParameters(Frontend.getInstance().getLoggedInUser().getId(),
vm.getId());
final AsyncQuery<VdcQueryReturnValue> portalUserReconnectPermissionQuery = new AsyncQuery<>(result -> {
boolean returnValue = result.getReturnValue();
if (returnValue) {
displayConsoleConnectConfirmPopup(command);
} else {
displayUserCantReconnectDialog();
}
});
final AsyncQuery<VdcQueryReturnValue> consoleUserReconnectPermissionQuery = new AsyncQuery<>(result -> {
boolean returnValue = result.getReturnValue();
if (returnValue) {
command.execute();
} else {
Frontend.getInstance().runQuery(VdcQueryType.HasAdElementReconnectPermission, portalUserReconnectPermParams, portalUserReconnectPermissionQuery);
}
});
Frontend.getInstance().runQuery(VdcQueryType.HasAdElementReconnectPermission, consoleUserReconnectPermParams, consoleUserReconnectPermissionQuery);
}
private void displayUserCantReconnectDialog() {
final ErrorPopupManager popupManager =
(ErrorPopupManager) TypeResolver.getInstance().resolve(ErrorPopupManager.class);
popupManager.show(ConstantsManager.getInstance().getConstants().userCantReconnectToVm());
}
private void displayConsoleConnectConfirmPopup(final UICommand onConfirmCommand) {
ConfirmationModel model = new ConfirmationModel();
parentModel.setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().confirmConsoleConnect());
model.setHelpTag(HelpTag.confirm_console_connect);
model.setHashName("confirm_console_connect"); //$NON-NLS-1$
model.setMessage(ConstantsManager.getInstance().getConstants().confirmConsoleConnectMessage());
UICommand confirmAndCloseCommand = new UICommand("Confirm", new BaseCommandTarget() { //$NON-NLS-1$
@Override
public void executeCommand(UICommand uiCommand) {
onConfirmCommand.execute();
parentModel.setWindow(null);
}
});
confirmAndCloseCommand.setTitle(ConstantsManager.getInstance().getConstants().ok());
confirmAndCloseCommand.setIsDefault(true);
model.getCommands().add(confirmAndCloseCommand);
UICommand cancelCommand = new UICommand("Cancel", new BaseCommandTarget() { //$NON-NLS-1$
@Override
public void executeCommand(UICommand uiCommand) {
parentModel.setWindow(null);
}
});
cancelCommand.setTitle(ConstantsManager.getInstance().getConstants().cancel());
cancelCommand.setIsCancel(true);
model.getCommands().add(cancelCommand);
}
public static void makeConsoleConfigRequest(String fileName, String contentType, String configFileContent) {
final FlowPanel innerPanel = new FlowPanel();
innerPanel.add(buildTextArea("contenttype", contentType));//$NON-NLS-1$
innerPanel.add(buildTextArea("content", URL.encodeQueryString(configFileContent)));//$NON-NLS-1$
innerPanel.add(buildTextArea("encodingtype", "plain"));//$NON-NLS-1$ $NON-NLS-2$
final FormPanel formPanel = new FormPanel(); //$NON-NLS-1$
formPanel.setMethod(FormPanel.METHOD_POST);
formPanel.getElement().setId("conform" + Double.valueOf(Math.random()).toString());//$NON-NLS-1$
formPanel.setWidget(innerPanel);
formPanel.setAction(GET_ATTACHMENT_SERVLET_URL + fileName);
formPanel.setEncoding(FormPanel.ENCODING_URLENCODED);
formPanel.setVisible(false);
// clean-up after form submit
formPanel.addSubmitCompleteHandler(event -> RootPanel.get().remove(formPanel));
RootPanel.get().add(formPanel);
FormElement.as(formPanel.getElement()).submit();
}
private static TextArea buildTextArea(String name, String value) {
TextArea textArea = new TextArea();
textArea.setName(name);
textArea.setValue(value);
return textArea;
}
protected String getClientTitle() {
return getEntity().getName() + ":%d"; //$NON-NLS-1$
}
@Override
public void cleanup() {
cleanupEvents(getErrorEvent());
super.cleanup();
}
}